<template>
  <div class="process-container">
    <div ref="ProcessContainer" id="processContainer"></div>
    <!-- 节点面板 -->
    <SectionList ref="SectionList" :lf="lf"></SectionList>
    <!-- 属性面板 -->
    <PropertyPanel
      ref="PropertyPanel"
      :lf="lf"
      :form="form"
      :current-node="currentData"
    ></PropertyPanel>
    <!-- 控制面板 -->
    <Control :lf="lf"></Control>
  </div>
</template>
<script>
import LogicFlow from "@logicflow/core";
import { Menu } from "@logicflow/extension";
import "@logicflow/core/dist/style/index.css";
import "@logicflow/extension/lib/style/index.css";
import { registerSection, registerEnd, registerStart } from "./registerNode";
import SectionList from "./sectionList";
import PropertyPanel from "./propertyPanel";
import Control from "./control";
const defaultNodes = [
  {
    id: "1",
    type: "start",
    x: 300,
    y: 100,
    text: {
      x: 300,
      y: 100,
      value: "开始",
    },
  },
  {
    id: "2",
    type: "end",
    x: 300,
    y: 400,
    text: {
      x: 300,
      y: 400,
      value: "结束",
    },
  },
];
export default {
  components: { SectionList, PropertyPanel, Control },
  props: {
    form: {
      type: Object,
      default: () => ({}),
    },
    processRouteData: {
      type: Object,
      default: null,
    },
  },
  data() {
    return {
      lf: null,
      data: {
        // 节点
        nodes: [...defaultNodes],
        // 边
        edges: [],
      },
      // 点击选中的节点
      currentData: {},
    };
  },
  created() {
    window.addEventListener("resize", this.resize);
  },
  methods: {
    init() {
      if (!this.$refs.ProcessContainer) {
        return;
      }
      this.$refs.SectionList.init();

      const ele = document.querySelector("#processContainer");
      // 渲染画布
      this.$nextTick(() => {
        const lf = new LogicFlow({
          container: ele,
          width: ele.offsetWidth,
          height: ele.offsetHeight,
          background: {
            backgroundColor: "#f7f9ff",
          },
          // grid: {
          //   size: 20,
          //   visible: true,
          //   type: "dot",
          //   config: {
          //     color: "#cccccc",
          //     thickness: 1,
          //   },
          // },
          keyboard: {
            enabled: true,
            shortcuts: [
              {
                keys: ["delete", "backspace"],
                callback: () => {
                  // 当前选中节点/线
                  const selectElements = this.lf.getSelectElements();
                  const allEle = [
                    ...selectElements.edges,
                    ...selectElements.nodes,
                  ];
                  // 删除选中的点/线，除开始/结束节点外
                  allEle.forEach((e) => {
                    if (!["start", "end"].includes(e.type)) {
                      this.lf.deleteElement(e.id);
                    }
                  });
                },
              },
              {
                keys: ["Up", "Down", "Right", "Left"],
                callback: (event) => {
                  // 当前选中节点/线
                  const selectElements = this.lf.getSelectElements();
                  const allEle = [
                    ...selectElements.edges,
                    ...selectElements.nodes,
                  ];

                  let param = [];
                  switch (event.key) {
                    // 左
                    case "ArrowLeft":
                      param = [-1, 0];
                      break;
                    // 右
                    case "ArrowRight":
                      param = [1, 0];
                      break;
                    // 上
                    case "ArrowUp":
                      param = [0, -1];
                      break;
                    // 下
                    case "ArrowDown":
                      param = [0, 1];
                      break;
                    default:
                      break;
                  }

                  if (!param.length) {
                    return;
                  }

                  allEle.forEach((e) => {
                    console.log(
                      "this.lf.graphModel.moveNode",
                      this.lf.graphModel.moveNode
                    );
                    this.lf.graphModel.moveNode(e.id, ...param);
                  });
                },
              },
            ],
          },
          textEdit: false,
          edgeTextEdit: false,
          adjustEdgeStartAndEnd: true,
          multipleSelectKey: "shift",
          plugins: [Menu],
        });
        this.lf = lf;
        // 设置主题
        this.setTheme();
        // 注册节点
        this.registerNode();
        // 配置右键菜单
        this.setMenu();
        // 渲染数据
        this.render();
        // 注册事件
        this.handleEvent();
      });
    },
    // 设置主题
    setTheme() {
      this.lf.setTheme({
        baseNode: {
          fill: "#FFFFFF",
          stroke: "#666666",
          strokeWidth: 2,
        },
        polyline: {
          stroke: "#666666",
          strokeWidth: 2,
        },
      });
    },
    // 注册节点
    registerNode() {
      registerSection(this.lf);
      registerEnd(this.lf);
      registerStart(this.lf);
    },
    // 配置右键菜单
    setMenu() {
      this.lf.extension.menu.setMenuConfig({
        edgeMenu: [
          {
            text: "删除",
            callback: (edge) => {
              this.lf.deleteEdge(edge.id);
            },
          },
        ], // 删除默认的边右键菜单
      });
    },
    // 绑定事件
    handleEvent() {
      this.lf.on("node:click", ({ data }) => {
        if (data?.type == "section") {
          this.currentData = data;
        }
        // this.$data.clickNode = data
        // this.$data.dialogVisible = true
      });
      this.lf.on("edge:click", ({ data }) => {
        // console.log("edge:click", data);
        //  this.$data.clickNode = data
        //   this.$data.dialogVisible = true
      });
      this.lf.on("element:click", () => {
        this.currentData = null;
        // this.hideAddPanel()
      });
      this.lf.on("edge:add", ({ data }) => {
        // console.log("edge:add", data);
      });
      this.lf.on("node:mousemove", ({ data }) => {
        // console.log("node:mousemove");
      });
      this.lf.on("blank:click", () => {
        this.currentData = null;
        // this.hideAddPanel()
      });
      this.lf.on("connection:not-allowed", (data) => {
        // this.msgError(data.msg);
      });
      this.lf.on("node:mousemove", () => {
        // console.log("on mousemove");
      });
    },
    render() {
      this.lf.render(this.data);
    },
    getGraphData() {
      return this.lf.getGraphData();
    },
    resetData() {
      this.data = {
        // 节点
        nodes: [...defaultNodes],
        // 边
        edges: [],
      };

      this.currentData = null;
    },
    initData(newData) {
      const _nodes = newData?.nodes?.length ? newData.nodes : [...defaultNodes];
      const _edges = newData?.edges?.length ? newData.edges : [];
      this.data = {
        // 节点
        nodes: _nodes,
        // 边
        edges: _edges,
      };
      console.log(this.data);
    },
    resize() {
      this.$nextTick(() => {
        const ProcessContainer = this.$refs.ProcessContainer;
        if (this.lf && ProcessContainer) {
          this.lf.resize(
            ProcessContainer.offsetWidth,
            ProcessContainer.offsetHeight
          );
        }
      });
    },
  },
  watch: {
    processRouteData: {
      handler(newVal) {
        if (newVal) {
          this.initData(newVal);
        } else {
          this.resetData();
        }
        if (this.lf) {
          this.lf.clearData();
        }
        this.currentData = null;
        this.$nextTick(() => {
          this.init();
        });
      },
      immediate: true,
    },
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.resize);
  },
};
</script>
<style lang="less" scoped>
.process-container {
  width: 100%;
  height: 100%;
  min-width: 600px;
  min-height: 400px;
  position: relative;
  #processContainer {
    width: 100%;
    height: 100%;
  }
}
</style>
